package com.myplaylist.android.service;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.List;
import java.util.Timer;

import org.xmlpull.v1.XmlSerializer;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.util.Xml;

import com.myplaylist.android.model.Track;
import com.myplaylist.android.persistence.IRepositoryManager;
import com.myplaylist.android.persistence.RepositoryManager;
import com.myplaylist.android.utils.Constants;
import com.myplaylist.android.utils.Discoverer;
import com.myplaylist.android.utils.NetworkInfoCredentials;
import com.myplaylist.android.utils.TrackHandlerTask;

public class MyPlaylistService extends Service {

	private static final int DELAY = 10000;
	private static final String QUEUECHANGED_HTC = "com.htc.music.queuechanged";
	private static final String PLAYBACKCOMPLETE_HTC = "com.htc.music.playbackcomplete";
	private static final String PLAYSTATECHANGED_HTC = "com.htc.music.playstatechanged";
	private static final String METACHANGED_HTC = "com.htc.music.metachanged";
	private static final String QUEUECHANGED = "com.android.music.queuechanged";
	private static final String PLAYBACKCOMPLETE = "com.android.music.playbackcomplete";
	private static final String PLAYSTATECHANGED = "com.android.music.playstatechanged";
	private static final String METACHANGED = "com.android.music.metachanged";
	public static final String SERVICECMD = "com.android.music.musicservicecommand";
	public static final String CMDNAME = "command";
	public static final String CMDTOGGLEPAUSE = "togglepause";
	public static final String CMDSTOP = "stop";
	public static final String CMDPAUSE = "pause";
	public static final String CMDPREVIOUS = "previous";
	public static final String CMDNEXT = "next";
	private BroadcastReceiver musicReceiver;

	private String currentAuthor;
	private String currentTitle;
	protected Timer timer;

	private IRepositoryManager repositoryManager;
	private TrackHandler trackHandler;
	protected boolean isMusicPlaying;
	private BroadcastReceiver wifiReceiver;
	protected WifiManager wifiManager;
	protected Discoverer discoverer;
	protected NetworkInfoCredentials networkInfoCredentials;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();

		repositoryManager = RepositoryManager
				.getInstance(getApplicationContext());
		trackHandler = new TrackHandler();

		currentAuthor = null;
		currentTitle = null;

		musicReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				Log.i("Valti ", action);
				// String album = intent.getStringExtra("album");

				if (action.equals(METACHANGED)
						|| action.equals(METACHANGED_HTC)) {
					currentAuthor = intent.getStringExtra("artist");
					currentTitle = intent.getStringExtra("track");
					Log.d("Current track", currentAuthor + "|" + currentTitle);
					timer = new Timer();
					timer.schedule(new TrackHandlerTask(trackHandler,
							currentAuthor, currentTitle), DELAY);
					isMusicPlaying = true;
				} else if (action.equals(PLAYSTATECHANGED)
						|| action.equals(PLAYSTATECHANGED_HTC)) {
					isMusicPlaying = !isMusicPlaying;
					if (isMusicPlaying) {
						timer = new Timer();
						timer.schedule(new TrackHandlerTask(trackHandler,
								currentAuthor, currentTitle), DELAY);
					}
				} else {
					timer = new Timer();
					isMusicPlaying = false;
				}
			}
		};
		
		wifiReceiver = new BroadcastReceiver() {
			
        	private Socket socket;

			@Override
        	public void onReceive(Context context, Intent intent) {
        		NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        		if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {

        			if (networkInfo.isConnected()) {
        				wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        				discoverer = new Discoverer(wifiManager);
        				synchronized (this) {
							networkInfoCredentials = discoverer.discover();
								try {
									sendTopTenToServer();
								} catch (Exception e) {
									// TODO Auto-generated catch block
								}
						}
        			} else {
            			synchronized (this) {
    						networkInfoCredentials = null;
    					}
            		}
        		} 
        	}

			private void sendTopTenToServer() throws Exception {
				List<Track> topTenTrackList = repositoryManager.getTopTen();
				if (topTenTrackList.size() != 0) {
					XmlSerializer xmlSerializer = Xml.newSerializer();
					StringWriter stringWriter = new StringWriter();

					xmlSerializer.setOutput(stringWriter);
					xmlSerializer.startDocument("UTF-8", true);
					xmlSerializer.startTag("", "tracklist");

					for (int i = 0; i < topTenTrackList.size(); i++) {
						xmlSerializer.startTag("", "track");
						xmlSerializer.attribute("", "title", topTenTrackList.get(i).getTitle());
						xmlSerializer.attribute("", "author", topTenTrackList.get(i).getAuthor());
						xmlSerializer.attribute("", "score", "" + topTenTrackList.get(i).getScore());
						xmlSerializer.endTag("", "track");
					}
					xmlSerializer.endTag("", "tracklist");
					xmlSerializer.endDocument();

					socket = new Socket(InetAddress.getByName(networkInfoCredentials.getServerIp()), Integer.parseInt(networkInfoCredentials.getServerPort()));

					PrintWriter pw = new PrintWriter(socket.getOutputStream());

					Log.i("XML String", stringWriter.toString());

					pw.write(stringWriter.toString());
					pw.flush();

					pw.close();

					if (socket != null) {
						socket.close();
					}
				}
			}
		};
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		unregisterReceiver(musicReceiver);
		unregisterReceiver(wifiReceiver);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);

		IntentFilter iF = new IntentFilter();
		iF.addAction(METACHANGED);
		iF.addAction(PLAYSTATECHANGED);
		iF.addAction(PLAYBACKCOMPLETE);
		iF.addAction(QUEUECHANGED);
		iF.addAction(METACHANGED_HTC);
		iF.addAction(PLAYSTATECHANGED_HTC);
		iF.addAction(PLAYBACKCOMPLETE_HTC);
		iF.addAction(QUEUECHANGED_HTC);
		registerReceiver(musicReceiver, iF);
		
		registerReceiver(wifiReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
	}

	public class TrackHandler extends Handler {

		@Override
		public void handleMessage(Message msg) {
			if (isMusicPlaying) {
				String author = msg.getData().getString(Constants.KEY_AUTHOR);
				String title = msg.getData().getString(Constants.KEY_TITLE);

				if ((author != null) && (title != null)
						&& (author.equals(currentAuthor))
						&& (title.equals(currentTitle))) {
					repositoryManager.add(new Track(currentTitle,
							currentAuthor, 0));
				}
			}
		}

	}

}
